package com.micro.ai.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.micro.ai.auth.dto.TenantCreateRequest;
import com.micro.ai.auth.dto.TenantDTO;
import com.micro.ai.auth.dto.TenantUpdateRequest;
import com.micro.ai.auth.entity.Tenant;
import com.micro.ai.auth.mapper.TenantMapper;
import com.micro.ai.auth.service.TenantService;
import com.micro.ai.commons.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.stream.Collectors;

/**
 * 租户服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class TenantServiceImpl implements TenantService {

    @Autowired
    private TenantMapper tenantMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TenantDTO createTenant(TenantCreateRequest request) {
        // 检查子域名是否已存在
        if (existsBySubdomain(request.getSubdomain())) {
            throw new BusinessException("子域名已存在: " + request.getSubdomain());
        }

        Tenant tenant = new Tenant();
        BeanUtils.copyProperties(request, tenant);

        // 设置默认值
        tenant.setStatus("pending"); // 新租户默认待审核
        if (!StringUtils.hasText(tenant.getPlanType())) {
            tenant.setPlanType("free");
        }

        // 设置试用时间（30天）
        tenant.setTrialEndsAt(LocalDateTime.now().plusDays(30));

        tenant.setCreatedAt(LocalDateTime.now());
        tenant.setUpdatedAt(LocalDateTime.now());

        tenantMapper.insert(tenant);

        log.info("创建租户成功: tenantId={}, name={}, subdomain={}", tenant.getId(), tenant.getName(), tenant.getSubdomain());

        return convertToDTO(tenant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TenantDTO updateTenant(String tenantId, TenantUpdateRequest request) {
        Tenant tenant = tenantMapper.selectById(tenantId);
        if (tenant == null) {
            throw new BusinessException("租户不存在: " + tenantId);
        }

        // 更新字段
        if (StringUtils.hasText(request.getName())) {
            tenant.setName(request.getName());
        }
        if (StringUtils.hasText(request.getStatus())) {
            tenant.setStatus(request.getStatus());
        }
        if (StringUtils.hasText(request.getPlanType())) {
            tenant.setPlanType(request.getPlanType());
            // 更新套餐时更新订阅结束时间
            if (!"free".equals(request.getPlanType())) {
                tenant.setSubscriptionEndsAt(LocalDateTime.now().plusYears(1));
            }
        }
        if (StringUtils.hasText(request.getContactEmail())) {
            tenant.setContactEmail(request.getContactEmail());
        }
        if (StringUtils.hasText(request.getContactPhone())) {
            tenant.setContactPhone(request.getContactPhone());
        }
        if (StringUtils.hasText(request.getWebsite())) {
            tenant.setWebsite(request.getWebsite());
        }
        if (StringUtils.hasText(request.getCountry())) {
            tenant.setCountry(request.getCountry());
        }
        if (StringUtils.hasText(request.getProvince())) {
            tenant.setProvince(request.getProvince());
        }
        if (StringUtils.hasText(request.getCity())) {
            tenant.setCity(request.getCity());
        }
        if (StringUtils.hasText(request.getAddress())) {
            tenant.setAddress(request.getAddress());
        }
        if (StringUtils.hasText(request.getPostalCode())) {
            tenant.setPostalCode(request.getPostalCode());
        }

        tenant.setUpdatedAt(LocalDateTime.now());
        tenantMapper.updateById(tenant);

        log.info("更新租户成功: tenantId={}, name={}", tenantId, tenant.getName());

        return convertToDTO(tenant);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTenant(String tenantId) {
        Tenant tenant = tenantMapper.selectById(tenantId);
        if (tenant == null) {
            throw new BusinessException("租户不存在: " + tenantId);
        }

        // 物理删除租户
        tenantMapper.deleteById(tenantId);

        log.info("删除租户成功: tenantId={}", tenantId);
    }

    @Override
    public TenantDTO getTenantById(String tenantId) {
        Tenant tenant = tenantMapper.selectById(tenantId);
        if (tenant == null) {
            throw new BusinessException("租户不存在: " + tenantId);
        }
        return convertToDTO(tenant);
    }

    @Override
    public TenantDTO getTenantBySubdomain(String subdomain) {
        LambdaQueryWrapper<Tenant> query = new LambdaQueryWrapper<>();
        query.eq(Tenant::getSubdomain, subdomain);
        Tenant tenant = tenantMapper.selectOne(query);
        if (tenant == null) {
            throw new BusinessException("租户不存在: " + subdomain);
        }
        return convertToDTO(tenant);
    }

    @Override
    public Page<TenantDTO> listTenants(int pageNum, int pageSize, String keyword, String status, String planType) {
        Page<Tenant> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Tenant> query = new LambdaQueryWrapper<>();

        if (StringUtils.hasText(keyword)) {
            query.and(q -> q.like(Tenant::getName, keyword)
                    .or().like(Tenant::getSubdomain, keyword)
                    .or().like(Tenant::getContactEmail, keyword));
        }
        if (StringUtils.hasText(status)) {
            query.eq(Tenant::getStatus, status);
        }
        if (StringUtils.hasText(planType)) {
            query.eq(Tenant::getPlanType, planType);
        }

        query.orderByDesc(Tenant::getCreatedAt);

        Page<Tenant> tenantPage = tenantMapper.selectPage(page, query);

        Page<TenantDTO> dtoPage = new Page<>(tenantPage.getCurrent(), tenantPage.getSize(), tenantPage.getTotal());
        dtoPage.setRecords(tenantPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList()));

        return dtoPage;
    }

    @Override
    public boolean existsBySubdomain(String subdomain) {
        LambdaQueryWrapper<Tenant> query = new LambdaQueryWrapper<>();
        query.eq(Tenant::getSubdomain, subdomain);
        return tenantMapper.selectCount(query) > 0;
    }

    /**
     * 转换为DTO
     */
    private TenantDTO convertToDTO(Tenant tenant) {
        if (tenant == null) {
            return null;
        }
        TenantDTO dto = new TenantDTO();
        BeanUtils.copyProperties(tenant, dto);
        return dto;
    }
}

